package com.hantang.web.dao;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Transaction;

import com.hantang.web.dao.ds.ArticlePO;
import com.hantang.web.dao.ds.UserPO;
import com.hantang.web.data.ArticleData;

public class ArticleDao extends BaseDao {
	private static Logger logger = Logger.getLogger(ArticleDao.class);
	public static ArticlePO convertData2Po(ArticleData data)
	{
		if(data == null){
			return null;
		}
		ArticlePO po = new ArticlePO();
		
		if(data.getAuthor() != null)
		{
			String useruuid = new UserDao().getUuidByName(data.getAuthor());
			if(useruuid != null)
			{
				UserPO upo = new UserPO();
				upo.setUuid(useruuid);
				po.setAuthor(upo);
			}else{
				logger.error("convertData2Po, this username " + data.getAuthor() + " is not exsit!!!");
			}
		}else{
			logger.info("convertData2Po, data.getAuthor() is null!!!");
		}
		
		po.setStatus(data.getStatus());
		po.setCategory(data.getCategory());
		po.setContent(data.getContent());
		po.setId(data.getId());
		po.setKeyWords(data.getKeyWords());
		po.setPublishTime(data.getPublishTime());
		po.setRemarks(data.getRemarks());
		po.setTitle(data.getTitle());
		po.setUpdateTime(data.getUpdateTime());
		
		return po;
	}
	
	public static ArticleData convertPo2Data(ArticlePO p)
	{
		if(p == null){
			return null;
		}
		ArticleData d = new ArticleData();
		d.setStatus(p.getStatus());
		d.setAuthor(p.getAuthor().getName());
		d.setCategory(p.getCategory());
		d.setContent(p.getContent());
		d.setId(p.getId());
		d.setKeyWords(p.getKeyWords());
		d.setPublishTime(p.getPublishTime());
		d.setRemarks(p.getRemarks());
		d.setTitle(p.getTitle());
		d.setUpdateTime(p.getUpdateTime());
		
		return d;
	}
	
	public ArticleData loadData(long id)
	{
		ArticleData data = null;
		logger.info("loadData, id:" + id);
		try{
			this.openSession();
			ArticlePO obj = (ArticlePO)this.session.get(ArticlePO.class, id);
			if(obj != null)
			{
				data = convertPo2Data(obj);
			}		
		}catch(Exception e){
			logger.error(e.getStackTrace());
			e.printStackTrace();
		}finally{
			this.closeSession();			
		}
		return data;
	}
	
	public boolean deleteData(long id)
	{
		logger.info("deleteData, id:"  + id);
		ArticlePO po = new ArticlePO();
		po.setId(id);
		boolean isOk = this.delete(po);
		return isOk;
	}
	
	public long saveData(ArticleData data)
	{
		if(data == null){
			logger.error("saveData, data is null!");
			return -1;
		}
		ArticlePO po = convertData2Po(data);
		this.save(po);
		logger.info("saveData, return Id:" + po.getId());
		data.setId(po.getId());
		return po.getId();
	}
	
	public boolean updateData(ArticleData data)
	{
		boolean isOk = false;
		
		Transaction tx = null;
		 try{
			 this.openSession();	
			 ArticlePO obj = (ArticlePO)this.session.get(ArticlePO.class, data.getId());
			 if(obj != null){
//				 ArticlePO po = convertData2Po(data);
				 
//				 if(obj.getAuthor() != null){
//					 po.setAuthor(obj.getAuthor());
//				 }
				 
				 if(data.getStatus() != 0){
					 obj.setStatus(data.getStatus());
				 }
				 
				 if(data.getCategory() != null){
					 obj.setCategory(data.getCategory());
				 }
				 if(data.getContent() != null){
					 obj.setContent(data.getContent());
				 }
				 if(data.getKeyWords() != null){
					 obj.setKeyWords(data.getKeyWords());
				 }
				 if(data.getPublishTime() != null){
					 obj.setPublishTime(data.getPublishTime());
				 }
				 if(data.getTitle() != null){
					 obj.setTitle(data.getTitle());
				 }
				 tx = this.session.beginTransaction();
				 this.session.update(obj);
				 tx.commit();
				 isOk = true;
			 }
		 }catch(HibernateException e){
			 logger.error("HibernateException: ", e);
			 e.printStackTrace();
			 if(tx != null){
				 tx.rollback();
			 }
		 }
		 finally{
			 this.closeSession();				 
		 }
		return isOk;
	}
	
	
	@SuppressWarnings("unchecked")
	public List<ArticleData> queryDatas(Date lastUpdatetime, int count)
	{
		List<ArticleData> datas = new ArrayList<ArticleData>();
		try{
			this.openSession();
			Query query = session.createQuery("select a from ArticlePO as a where a.updateTime < ? and a.publishTime is not null and a.status=0 order by a.updateTime DESC")
								.setDate(0, lastUpdatetime).setMaxResults(count);// 
			
			List<ArticlePO> results = query.list();
			if (!results.isEmpty()) {
				for (int i = 0; i < results.size(); i++)
				{
					ArticleData d = convertPo2Data(results.get(i));
					datas.add(d);
				}
			}		
		}catch(Exception e){
			logger.error(e.getStackTrace());
			e.printStackTrace();
		}finally{
			this.closeSession();			
		}
		logger.info("queryDatas, fromId " + lastUpdatetime + " count "+ count + ", return size:" + datas.size());
		
		return datas; // do not return a "null", since yaml doesn't like a null input.
	}
	

	@SuppressWarnings("unchecked")
	public List<ArticleData> queryDatasByUser(Date lastUpdatetime, int count, String username, boolean onlyPub)
	{
		List<ArticleData> datas = new ArrayList<ArticleData>();
		try{
			this.openSession();
			
			String sql = "select a from ArticlePO as a where a.updateTime < ? and a.author.name = ? and a.publishTime is not null and a.status=0 order by a.updateTime DESC";
			if (!onlyPub) {
				sql = "select a from ArticlePO as a where a.updateTime < ? and a.author.name = ? and a.status=0 order by a.updateTime DESC";
			}
			
			Query query = session.createQuery(sql)
								.setDate(0, lastUpdatetime)
								.setString(1, username)
								.setMaxResults(count);//.setInteger(1, count);
			
			List<ArticlePO> results = query.list();
			if (!results.isEmpty()) {
				for (int i = 0; i < results.size(); i++)
				{
					ArticleData d = convertPo2Data(results.get(i));
					datas.add(d);
				}
			}		
		}catch(Exception e){
			logger.error("Exception", e);
			e.printStackTrace();
			datas = null;
		}finally{
			this.closeSession();			
		}
		logger.info("queryDatas, fromId " + lastUpdatetime + " count "+ count + ", return size:" + datas.size());
		
		return datas; // do not return a "null", since yaml doesn't like a null input.
	}
}
